/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2014年7月7日         Root.Lu
 */

package com.tianci.appstore.controller.manager;

import android.os.RemoteException;

import com.coocaa.x.app.framework.app.LiteAppApplication;
import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.utils.Android;
import com.coocaa.x.framework.utils.LiteURI;
import com.coocaa.x.framework.utils.LogUtils;
import com.coocaa.x.framework.utils.Size2String;
import com.coocaa.x.service.XServiceManager;
import com.coocaa.x.service.litecontent.LiteContentServiceConnecter;
import com.coocaa.x.service.litecontent.data.apps.com_coocaa_app.AppUpdateBean;
import com.coocaa.x.service.litecontent.data.apps.com_coocaa_app.RP_Installed_Apps;
import com.coocaa.x.service.litecontent.data.apps.com_coocaa_app.RP_Update_Apps;
import com.coocaa.x.service.litedownloader.aidl.IDownloaderServiceListener;
import com.coocaa.x.service.litedownloader.data.DownloadError;
import com.coocaa.x.service.litedownloader.data.DownloadExtra;
import com.coocaa.x.service.litedownloader.data.DownloadTask;
import com.coocaa.x.service.litedownloader.data.ProcessInfo;
import com.coocaa.x.service.litedownloader.data.TaskInfo.TASK_STATE;
import com.coocaa.x.service.litepm.aidl.ILitePMInstallListener;
import com.coocaa.x.service.litepm.data.AppInfo;
import com.coocaa.x.service.litepm.data.InstallParams;
import com.skyworth.logsdk.appstore.LogAPIForAppStore;
import com.skyworth.webSDK.webservice.tcappstore.AppDetailData;
import com.skyworth.webSDK.webservice.tcappstore.AppStoreException;
import com.tianci.appstore.R;
import com.tianci.appstore.controller.AppStoreBaseController;
import com.tianci.appstore.dataprovider.AppDataProvider;
import com.tianci.appstore.ui.data.SkyAppDetailData.AppStatus;
import com.tianci.appstore.ui.data.SkyListAppData.ListType;
import com.tianci.appstore.ui.data.SkyListProgressData;
import com.tianci.appstore.ui.detail.AppDownloadListener;
import com.tianci.appstore.ui.list.download.DownloadListDataListener;
import com.tianci.appstore.ui.list.upgrade.UpgradeListDataListener;
import com.tianci.appstore.ui.widget.TipToast;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

public class UpdateManagerController extends AppStoreBaseController {
    private static UpdateManagerController instance = new UpdateManagerController();

    public static UpdateManagerController getInstance() {
        return instance;
    }

    /**
     * @author Root.Lu
     * @version TODO (write something)
     * @ClassName ACTION
     * @Description TODO (write something)
     * @date 2014年7月8日
     */
    public enum ACTION {
        /**
         * @Fields DOWNLOAD_ALL TODO 开始全部
         */
        UPDATE_ALL,
        /**
         * @Fields PAUSE_ALL TODO 暂停全部
         */
        PAUSE_ALL,
        /**
         * @Fields PAUSE TODO暂停某一个
         */
        PAUSE,
        /**
         * @Fields START TODO开始某一个
         */
        START,
        /**
         * @Fields DELETE TODO 取消某一个
         */
        DELETE,
        /**
         * @Fields TO_FIRST TODO优先某一个
         */
        TO_FIRST,
        /**
         * @Fields INSTALL TODO 安装某一个
         */
        INSTALL,
        /**
         * @Fields SHOW_DETAIL TODO 显示某一个的更新信息
         */
        SHOW_DETAIL,
    }

    private ReentrantLock lock = new ReentrantLock();

    private List<AppUpdateBean> updateBeans = new ArrayList<AppUpdateBean>();

    private DownloadListDataListener datalistener = null;
    private AppDownloadListener downloadlistener = null;
    private UpgradeListDataListener upgradeListener = null;
    private HashMap<String, DownloadTask> taskMap = new HashMap<String, DownloadTask>();

    public void init(DownloadListDataListener listener, AppDownloadListener downloadlistener,
                     UpgradeListDataListener upgradeListener) {
        datalistener = listener;
        this.downloadlistener = downloadlistener;
        this.upgradeListener = upgradeListener;
        runOnThread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    XServiceManager.getLitePMService().addInstallListener(appPMstub);
                    XServiceManager.getDownloaderService().setListener(downloaderStub);
                    updateData();
                    updateUI();
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        runOnThread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    XServiceManager.getLitePMService().removeInstallListener(appPMstub);
                    XServiceManager.getDownloaderService().clearListener(downloaderStub);
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
        datalistener = new DownloadListDataListener() {
            @Override
            public void onDownloadListLoaded(int activeCount, int pauseCount, int otherCount, List<SkyListProgressData> dataList) {

            }

            @Override
            public void onRefreshDownloadCount(int activeCount, int pauseCount, int otherCount) {

            }

            @Override
            public void onRefreshShowInfo(String appId, String showInfo) {

            }
        };
        upgradeListener = new UpgradeListDataListener() {
            @Override
            public void onRefreshUpgradeInfo(String appId, String versionName, String upgradeInfo) {

            }
        };
        downloadlistener = new AppDownloadListener() {
            @Override
            public void onUpdateStatus(String appId, AppStatus status) {

            }

            @Override
            public void onUpdatePercent(String appId, int percent) {

            }
        };
    }

    private static Map<String, String> urlMap = new HashMap<String, String>();


    private String getDownurl(String appid, String usercount) {
        try {
            String downurl = null;
            synchronized (urlMap) {
                downurl = urlMap.get(appid);
            }
            if (downurl == null) {
                downurl = CoocaaApplication.getCoocaaWebService().getAppStoreService().getDownAddress(
                        Integer.valueOf(appid), usercount);
                urlMap.put(appid, downurl);
            }
            System.out.println("download url:" + downurl);
            return downurl;
        } catch (AppStoreException e) {
            LogAPIForAppStore.reportInterfaceError("获取应用下载地址接口",
                    Android.throwable2String(e));
            System.out.println("错误原因：" + e.getErrormsg());
        } catch (NumberFormatException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "";
    }

    public void handleAction(final ACTION action, final SkyListProgressData data) {
        runOnThread(new Runnable() {
            private void updateApp(AppUpdateBean bean) throws RemoteException, AppStoreException {
                DownloadTask task = null;
                String id = String.valueOf(bean.bean.appid);
                if (XServiceManager.getDownloaderService().hasTask(bean.bean.packagename)) {
                    task = XServiceManager.getDownloaderService().getTask(bean.bean.packagename);
                    if (task.info.state != TASK_STATE.FINISH)
                        XServiceManager.getDownloaderService().start(task);
                } else {
                    AppDetailData appDetail = CoocaaApplication.getCoocaaWebService().getAppStoreService().getAppDetail(
                            String.valueOf(bean.bean.appid), String.valueOf(bean.bean.version));
                    String download_url = getDownurl(
                            String.valueOf(bean.bean.appid), "");
                    LogUtils.d("download_url:" + download_url);
                    if (download_url != null) {
                        String download_path = AppDataProvider.getInstance().getDownloadPath();
                        DownloadExtra extra = new DownloadExtra(appDetail.id,
                                appDetail.packageName, appDetail.iconUrl, appDetail.title);
                        task = new DownloadTask(download_url);
                        task.title = appDetail.title;
                        task.url = download_url;
                        task.savepath = download_path;
                        task.filename = appDetail.packageName + ".apk";
                        task.extra = extra.toString();
                        XServiceManager.getDownloaderService().add(task);
                        XServiceManager.getDownloaderService().start(task);
                    }
                }
            }

            @Override
            public void run() {
                AppUpdateBean bean = null;
                String download_url = null;
                if (!(action == ACTION.UPDATE_ALL || action == ACTION.PAUSE_ALL)) {
                    bean = (AppUpdateBean) data.getObject();
                    download_url = getDownurl(String.valueOf(bean.bean.appid), "");
                }
                try {
                    switch (action) {
                        case SHOW_DETAIL: {
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            String info = mContext.getResources().getString(
                                    R.string.update_app_size)
                                    + Size2String.byte2Auto(Long.valueOf(bean.bean.filesize)) + "\n";
                            info += mContext.getResources().getString(R.string.update_update_time)
                                    + bean.bean.updatetime + "\n";
                            info += bean.bean.updateinfo;
                            upgradeListener.onRefreshUpgradeInfo(
                                    download_url,// String.valueOf(bean.bean.appid),
                                    String.format(
                                            mContext.getResources().getString(
                                                    R.string.update_info_version),
                                            String.valueOf(bean.bean.versionname)), info);
                            sendBtnClickLOG("显示更新详情", bean.bean.appid, bean.bean.appname);
                            break;
                        }
                        case UPDATE_ALL: {
                            sendBtnClickLOG("全部更新");
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            lock.lock();
                            for (AppUpdateBean _bean : updateBeans)
                                updateApp(_bean);
                            lock.unlock();
                            break;
                        }
                        case PAUSE_ALL: {
                            sendBtnClickLOG("全部暂停");
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            XServiceManager.getDownloaderService().stopAll();
                            break;
                        }
                        case START: {
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            updateApp(bean);
                            sendBtnClickLOG("开始更新", bean.bean.appid, bean.bean.appname);
                            break;
                        }
                        case PAUSE: {
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            if (XServiceManager.getDownloaderService().hasTask(download_url)) {
                                DownloadTask task = XServiceManager.getDownloaderService().getTask(
                                        download_url);
                                XServiceManager.getDownloaderService().stop(task);
                            }
                            sendBtnClickLOG("暂停更新", bean.bean.appid, bean.bean.appname);
                            break;
                        }
                        case DELETE: {
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            if (XServiceManager.getDownloaderService().hasTask(download_url)) {
                                DownloadTask task = XServiceManager.getDownloaderService().getTask(download_url);
                                XServiceManager.getDownloaderService().delete(task);
                            }
                            sendBtnClickLOG("取消更新", bean.bean.appid, bean.bean.appname);
                            break;
                        }
                        case TO_FIRST: {
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            if (XServiceManager.getDownloaderService().hasTask(download_url)) {
                                DownloadTask task = XServiceManager.getDownloaderService().getTask(download_url);
                                XServiceManager.getDownloaderService().toFirst(task);
                            }
                            sendBtnClickLOG("优先更新", bean.bean.appid, bean.bean.appname);
                            break;
                        }
                        case INSTALL: {
                            if (XServiceManager.getDownloaderService().hasTask(download_url)) {
                                DownloadTask task = XServiceManager.getDownloaderService().getTask(
                                        download_url);
                                InstallParams params = new InstallParams();
                                params.setFrom(InstallParams.INSTALL_FROM.COOCAA_MARKET);
                                XServiceManager.getLitePMService().install(
                                        task.savepath + task.filename, CoocaaApplication.isRoot(), params);
                            }
                            sendBtnClickLOG("安装", bean.bean.appid, bean.bean.appname);
                            break;
                        }
                        default:
                            break;
                    }
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (AppStoreException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }

    private List<AppUpdateBean> getUpdateBeans() {
        List<AppUpdateBean> appdatas = null;
        LiteURI uri = LiteURI.create("apps://com.coocaa.app/update_apps");
        String json = null;
        try {
            json = LiteContentServiceConnecter.getService().call(uri.toString());
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        if (json != null) {
            RP_Update_Apps rp = RP_Installed_Apps.parseJObject(json, RP_Update_Apps.class);
            appdatas = rp.resource.resource_items;
        }
        if (appdatas == null)
            appdatas = new ArrayList<AppUpdateBean>();
        return appdatas;
    }

    private void update() {
        try {
            int activeCount = 0;
            int pauseCount = 0;
            List<AppUpdateBean> updatelist = getUpdateBeans();
            List<DownloadTask> list = XServiceManager.getDownloaderService().getTaskList();
            if (list != null) {
                for (DownloadTask task : list) {
                    switch (task.info.state) {
                        case READY:
                            break;
                        case PROCESSING:
                            activeCount++;
                            break;
                        case STOPED:
                            pauseCount++;
                            break;
                        case FINISH:
                            break;
                        default:
                            continue;
                    }
                }
                datalistener.onRefreshDownloadCount(activeCount, pauseCount, updatelist.size());
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private void updateData() {
        List<AppUpdateBean> list = getUpdateBeans();
        lock.lock();
        updateBeans.clear();
        for (AppUpdateBean bean : list)
            updateBeans.add(bean);
        lock.unlock();
    }

    private void updateUI() {
        try {
            int activeCount = 0;
            int pauseCount = 0;
            List<SkyListProgressData> dataList = new ArrayList<SkyListProgressData>();
            int otherCount = updateBeans.size();
            taskMap.clear();
            lock.lock();
            for (AppUpdateBean bean : updateBeans) {
                String appid = String.valueOf(bean.bean.appid);
                SkyListProgressData data = new SkyListProgressData(ListType.UPGRADE_APP_LIST);
                data.setShowInfo(Size2String.byte2Auto(Long.valueOf(bean.bean.filesize)));
                data.setIconUrl("");
                data.setId(getDownurl(appid, ""));
                data.setPkgName(bean.bean.packagename);
                data.setTitle(bean.bean.appname);
                data.setObject(bean);
                if (XServiceManager.getDownloaderService().hasTask(getDownurl(appid, ""))) {
                    DownloadTask task = XServiceManager.getDownloaderService().getTask(getDownurl(appid, ""));
                    taskMap.put(bean.bean.packagename, task);
                    DownloadExtra extra = DownloadExtra.parseJObject(task.extra,
                            DownloadExtra.class);
                    if (bean.bean.packagename.equals(extra.pkgname)) {
                        switch (task.info.state) {
                            case READY:// 等待
                                activeCount++;
                                data.setStatus(AppStatus.WAITING);
                                break;
                            case PROCESSING:// 下载中
                                activeCount++;
                                if (task.info.length > 0) {
                                    int percent = (int) (task.info.current * 100 / task.info.length);
                                    data.setPercent(percent);
                                }
                                data.setStatus(AppStatus.DOWNLOADING);
                                break;
                            case STOPED:// 暂停
                                pauseCount++;
                                if (task.info.length > 0) {
                                    int percent = (int) (task.info.current * 100 / task.info.length);
                                    data.setPercent(percent);
                                }
                                data.setStatus(AppStatus.DOWNLOAD_PAUSED);
                                break;
                            case FINISH:// 安装
                                data.setStatus(AppStatus.DOWNLOADED);
                                break;
                            default:
                                data.setStatus(AppStatus.NOT_DOWNLOADED);
                                break;
                        }
                    }
                }
                dataList.add(data);
            }
            lock.unlock();
            otherCount = otherCount - activeCount - pauseCount;
            LogUtils.d("activeCount:" + activeCount + " pauseCount:" + pauseCount + " otherCount:"
                    + otherCount);
            UpdateManagerController.this.datalistener.onDownloadListLoaded(activeCount, pauseCount,
                    otherCount, dataList);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private ILitePMInstallListener.Stub appPMstub = new ILitePMInstallListener.Stub() {
        @Override
        public void onInstallStart(String apkfile, AppInfo appInfo, final InstallParams params) throws RemoteException {
            // TODO Auto-generated method stub
            lock.lock();
            final DownloadTask task = taskMap.get(appInfo.pkgName);
            lock.unlock();
            if (task != null) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        downloadlistener.onUpdateStatus(task.ID, AppStatus.INSTALLING);
                    }
                });
                update();
            }
        }

        @Override
        public void onInstallEnd(String arg0, AppInfo appInfo, int arg2, String arg3, final InstallParams params)
                throws RemoteException {
            // TODO Auto-generated method stub
            runOnThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    updateData();
                    updateUI();
                }
            });
        }
    };

    private IDownloaderServiceListener.Stub downloaderStub = new IDownloaderServiceListener.Stub() {
        @Override
        public void onReady(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdateStatus(task.ID, AppStatus.WAITING);
                }
            });
            update();
        }

        @Override
        public void onPrepare(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
        }

        @Override
        public void onStart(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdateStatus(task.ID, AppStatus.DOWNLOADING);
                }
            });
            update();
        }

        @Override
        public void onStop(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdateStatus(task.ID, AppStatus.DOWNLOAD_PAUSED);
                }
            });
            update();
        }

        @Override
        public void onProcessInfo(final DownloadTask task, final ProcessInfo info)
                throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdatePercent(task.ID, info.percent);
                }
            });
        }

        @Override
        public void onFinish(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdateStatus(task.ID, AppStatus.DOWNLOADED);
                }
            });
            update();
        }

        @Override
        public void onError(final DownloadTask task, final DownloadError error)
                throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdateStatus(task.ID, AppStatus.NOT_DOWNLOADED);
                }
            });
            update();
        }

        @Override
        public void onDelete(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdateStatus(task.ID, AppStatus.NOT_DOWNLOADED);
                }
            });
            updateUI();
        }
    };

    @Override
    public String getModuleName() {
        // TODO Auto-generated method stub
        return "";
    }
}
